package com.wsfPro.repositoryImpl;

import com.wsfPro.core.base.ProxyEntityManager;
import com.wsfPro.repository.AbstractRepository;
import com.wsfPro.repository.Persistable;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.ParameterizedType;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractRepositoryImpl<X extends Persistable, I>
    extends AbstractPersisTableRepositoryImpl<I>
    implements AbstractRepository<X, I>, ProxyEntityManager {
  protected final Logger log = LoggerFactory.getLogger(AbstractRepositoryImpl.class);
  // 反射对象
  private final Class<X> clazz;

  /** 构造函数反射泛型对象真实类型 */
  public AbstractRepositoryImpl() {
    //    获取new对象的泛型父类
    ParameterizedType pType = (ParameterizedType) this.getClass().getGenericSuperclass();
    // 获取类型参数的真是值，就是泛型参数的个数；
    this.clazz = (Class<X>) pType.getActualTypeArguments()[0];
    //    java.lang.String className = clazz.getSimpleName();
    log.info("service For the:" + clazz);
  }

  @Override
  public Class<X> getClazz() {
    return clazz;
  }

  @Override
  public X save(X entity) {
    super.save(entity);
    return entity;
  }

  @Override
  public X update(X entity) {
    return super.update(entity);
  }

  @Override
  public X findById(I id) {
    return super.findById(this.clazz, id);
  }

  @Override
  public List<X> findByFiled(String filed, Object o) {
    return super.findByFiled(this.clazz, filed, o);
  }

  @Override
  public List<X> findByFileds(LinkedHashMap<String, Object> linkedHashMap) {
    return super.findByFileds(this.clazz, linkedHashMap);
  }

  @Override
  public List<X> findAll() {
    return super.findAll(this.clazz);
  }

  @Override
  public List<X> findByNativeQuery(String sql, Map<String, Object> conditionParams) {
    return super.findByNativeQuery(sql, conditionParams, Transformers.aliasToBean(getClazz()));
  }

  @Override
  public List<X> findPageByNativeQueryFiled(String filed, Object o, int pageNo, int pageSize) {
    return super.findPageByNativeQueryFiled(this.clazz, filed, o, pageNo, pageSize);
  }

  @Override
  public Map<String, Object> findPageByNativeQueryFileds(
      String sql, Map<String, Object> conditionParams, Integer pageNo, Integer pageSize) {
    return super.findPageByNativeQueryFileds(
        sql, conditionParams, Transformers.aliasToBean(getClazz()), pageNo, pageSize);
  }

  @Override
  public Integer updateFileds(LinkedHashMap<String, Object> map) {
    return super.updateFileds(this.clazz, map);
  }

  @Override
  public boolean remove(X entity) {
    return super.remove(entity);
  }

  @Override
  public boolean deleteById(I id) {
    return super.deleteById(this.clazz, id);
  }

  @Override
  public boolean deleteByMap(Map paramsMap) {
    return super.deleteByMap(this.clazz, paramsMap);
  }

  @Override
  public boolean deleteByMap(Map paramsMap, String hql) {
    return super.deleteByMap(this.clazz, hql, paramsMap);
  }

  @Override
  public X findByIdClass(X entity, Object id) {
    return super.findByIdClass(entity, id);
  }

  // ---------------------------------first

  @Override
  public X first(String hql) {
    return super.first(this.clazz, hql);
  }

  @Override
  public X first(String hql, Object arg) {
    return super.first(this.clazz, hql, arg);
  }

  @Override
  public X first(String hql, Object arg, Object arg2) {
    return super.first(this.clazz, hql, arg, arg2);
  }

  @Override
  public X first(String hql, Object... args) {
    return super.first(this.clazz, hql, args);
  }

  // ---------------------------------single
  @Override
  public X single(String hql) {
    return super.single(this.clazz, hql);
  }

  @Override
  public X single(String hql, Object arg) {
    return super.single(this.clazz, hql, arg);
  }

  @Override
  public X single(String hql, Object arg, Object arg2) {
    return super.single(this.clazz, hql, arg, arg2);
  }

  @Override
  public X single(String hql, Object... args) {
    return super.single(this.clazz, hql, args);
  }

  // ---------------------------------list
  @Override
  public List<X> list(String hql) {
    return super.list(this.clazz, hql);
  }

  @Override
  public List<X> list(String hql, Object arg) {
    return super.list(this.clazz, hql, arg);
  }

  @Override
  public List<X> list(String hql, Object arg, Object arg2) {
    return super.list(this.clazz, hql, arg, arg2);
  }

  @Override
  public List<X> list(String hql, Object... args) {
    return super.list(this.clazz, hql, args);
  }

  // ---------------------------------top
  @Override
  public List<X> top(int top, String hql) {
    return super.top(top, this.clazz, hql);
  }

  @Override
  public List<X> top(int top, String hql, Object arg) {
    return super.top(top, this.clazz, hql, arg);
  }

  @Override
  public List<X> top(int top, String hql, Object arg, Object arg2) {
    return super.top(top, this.clazz, hql, arg, arg2);
  }

  @Override
  public List<X> top(int top, String hql, Object... args) {
    return super.top(top, this.clazz, hql, args);
  }
}
